home *** CD-ROM | disk | FTP | other *** search
- /* First, include our own supporting header files, i.e., clip.h */
- #include "clip.h"
-
- #include<exec/libraries.h>
- #include<intuition/intuition.h>
- #include<utility/tagitem.h>
- #include<graphics/text.h>
- #include<graphics/rastport.h>
- #include<intuition/screens.h>
- #include<libraries/gadtools.h>
-
- #include<string.h>
- #include<stdio.h>
-
- #include<clib/exec_protos.h>
- #include<clib/graphics_protos.h>
- #include<clib/intuition_protos.h>
- #include<clib/gadtools_protos.h>
-
- /* The library base global variables */
- /* (The different style of opening libraries requires these to be initialised to NULL) */
- struct Library* GfxBase = NULL;
- struct Library* IntuitionBase = NULL;
- struct Library* LayersBase = NULL;
- struct Library* GadToolsBase = NULL;
-
- /* The global handle on the palette gadget */
- struct Gadget* palgad = NULL;
- /* Global record of foreground pen */
- UBYTE pen;
-
- /* Need to give prototypes for our functions */
- void handleIDCMP(struct Window*);
- void setupWindow();
- void createWindow(struct Gadget*, struct Screen*, struct Menu*);
- int openLibs();
- void closeLibs();
- struct Menu* createMenuStrip(APTR);
- void setFgPen(struct Window*, int);
-
- /* Some constants for the position and size of our gadget */
- #define MYBUT_LEFT (10)
- #define MYBUT_TOP (5)
- #define MYBUT_WIDTH (80)
- #define MYBUT_HEIGHT (12)
- #define MYBUT_TEXT "Next Pen"
- #define MYBUT_ID (0)
-
- #define MYPAL_LEFT (170)
- #define MYPAL_TOP (2)
- #define MYPAL_WIDTH (109)
- #define MYPAL_HEIGHT (19)
- #define MYPAL_TEXT "Colour:"
- #define MYPAL_ID (1)
- #define MYPAL_DEPTH (4)
-
- /* The top gap required around the gadgets */
- #define MYTOPGAP (30)
-
- /* The initial pen colour */
- #define MYINITPEN (1)
-
- /* The start of the program */
- void main()
- {
- /* Use a different style of opening libraries... */
- if(openLibs())
- {
- /* Now do the real work */
- setupWindow();
- }
- /* Matched call to close libraries */
- closeLibs();
- }
-
- /* Try to open all the libraries -- return TRUE on success */
- int openLibs()
- {
- if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
- {
- printf("Error: could not open graphics.library\n");
- return FALSE;
- }
- if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
- {
- printf("Error: could not open intuition.library\n");
- return FALSE;
- }
- if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
- {
- printf("Error: could not open layers.library\n");
- return FALSE;
- }
- if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
- {
- printf("Error: could not open gadtools.library\n");
- return FALSE;
- }
- return TRUE;
- }
-
- /* Close any open library */
- void closeLibs()
- {
- if(GadToolsBase)
- CloseLibrary(GadToolsBase);
- if(LayersBase)
- CloseLibrary(LayersBase);
- if(IntuitionBase)
- CloseLibrary(IntuitionBase);
- if(GfxBase)
- CloseLibrary(GfxBase);
- }
-
- /* Setup the window -- do the GadTools stuff */
- void setupWindow()
- {
- struct Screen* scr;
- UWORD pens[] = { ~0 };
- /* Try to open a new screen with 16 colours (four bitplanes deep) */
- if(scr = OpenScreenTags(NULL,
- SA_Depth, 4,
- /* Enable 3D look by specifying SA_Pens */
- SA_Pens, pens,
- TAG_DONE))
- {
- APTR vinfo;
- /* Get the visual info so GadTools can render the gadgets nicely */
- if(vinfo = GetVisualInfo(scr, TAG_DONE))
- {
- /* We can initialise glist in its declaration */
- struct Gadget* glist = NULL;
- struct Gadget* gad;
- int offtop, offleft;
- struct NewGadget newgad;
- /* Initialised structure declaration: describes 8pt Topaz font */
- struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
- /* Start a GadTools gadget list */
- gad = CreateContext(&glist);
- /* The offsets of our window borders */
- offleft = scr->WBorLeft;
- offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
-
- /* Setup our first gadget */
- newgad.ng_TextAttr = &topazFont;
- newgad.ng_VisualInfo = vinfo;
- newgad.ng_LeftEdge = MYBUT_LEFT + offleft;
- newgad.ng_TopEdge = MYBUT_TOP + offtop;
- newgad.ng_Width = MYBUT_WIDTH;
- newgad.ng_Height = MYBUT_HEIGHT;
- newgad.ng_GadgetText = MYBUT_TEXT;
- newgad.ng_GadgetID = MYBUT_ID;
- newgad.ng_Flags = 0;
- /* Now create it and add it to our list */
- gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
-
- /* Setup our second gadget */
- /* (We can reuse newgad, and just change the different bits) */
- newgad.ng_LeftEdge = MYPAL_LEFT + offleft;
- newgad.ng_TopEdge = MYPAL_TOP + offtop;
- newgad.ng_Width = MYPAL_WIDTH;
- newgad.ng_Height = MYPAL_HEIGHT;
- newgad.ng_GadgetText = MYPAL_TEXT;
- newgad.ng_GadgetID = MYPAL_ID;
- newgad.ng_Flags = 0;
- /* Now create it and add it to our list */
- if(gad = CreateGadget(PALETTE_KIND, gad, &newgad,
- /* Initially selected pen */
- GTPA_Color, MYINITPEN,
- /* Depth: 2 to the power MYPAL_DEPTH colours */
- GTPA_Depth, MYPAL_DEPTH,
- /* Gadget will indicate selection */
- GTPA_IndicatorWidth, 16,
- TAG_DONE))
- {
- struct Menu* menustrip;
- /* Remember gadget pointer so we can affect it in message handler */
- palgad = gad;
- if(menustrip = createMenuStrip(vinfo))
- /* If succeeded then all gadgets and menus created */
- createWindow(glist, scr, menustrip);
- FreeMenus(menustrip);
- }
- else
- printf("Error: could not create gadget(s)\n");
- /* Free all the gadgets that were created */
- FreeGadgets(glist);
- FreeVisualInfo(vinfo);
- }
- else
- printf("Error: could not get visual info\n");
- CloseScreen(scr);
- }
- else
- printf("Error: could not create screen\n");
- }
-
- /* Create the menu strip, using GadTools menu functions */
- struct Menu* createMenuStrip(APTR vinfo)
- {
- /* The description of our menus */
- struct NewMenu mymenu[] =
- {
- { NM_TITLE, "Project", 0, 0, 0, 0,},
- { NM_ITEM, "Quit", "Q", 0, 0, 0,},
- { NM_TITLE, "Pen", 0, 0, 0, 0,},
- { NM_ITEM, "Next", "N", 0, 0, 0,},
- { NM_ITEM, "Prev", "P", 0, 0, 0,},
- { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
- { NM_ITEM, "Reset", "R", 0, 0, 0,},
- { NM_END, NULL, 0, 0, 0, 0,},
- };
- struct Menu* menustrip;
- if (menustrip = CreateMenus(mymenu, TAG_END))
- {
- if (LayoutMenus(menustrip, vinfo, TAG_END))
- /* Succeeded, so return menu strip */
- return menustrip;
- else
- {
- /* Failed, so must deallocate before returning */
- FreeMenus(menustrip);
- printf("Error: could not layout menus\n");
- }
- }
- else
- printf("Error: could not create menu strip\n");
- /* Failed, so return NULL */
- return NULL;
- }
-
- /* Actually open the window, in the normal way */
- void createWindow(struct Gadget* glist, struct Screen* scr, struct Menu* menustrip)
- {
- struct Window* win;
- /* Open our window */
- if(win = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- /* Make the window the same size as the screen */
- WA_Width, scr->Width,
- WA_Height, scr->Height,
- WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
- WA_Gadgets, glist,
- WA_CustomScreen, scr,
- TAG_DONE, 0))
- {
- /* If window opened, set clip region */
- if(setClipInternal(win))
- {
- /* Attach menu strip to window */
- if(SetMenuStrip(win, menustrip))
- {
- /* Let GadTools refresh its bits of the window */
- GT_RefreshWindow(win, NULL);
- /* Now handle messages */
- handleIDCMP(win);
- /* Remove menu strip */
- ClearMenuStrip(win);
- }
- else
- printf("Error: could not attach menus to window\n");
- removeClip(win);
- }
- else
- printf("Error: could not set clip region on window\n");
- CloseWindow(win);
- }
- else
- printf("Error: could not open window\n");
- }
-
- /* Our message handling code */
- void handleIDCMP(struct Window* win)
- {
- char* text = "Hello World!";
- int going = TRUE;
- int drawing = FALSE;
- setFgPen(win, MYINITPEN);
- /* Set the drawing mode to draw only the foreground of text, not the background */
- SetDrMd(win->RPort, JAM1);
- while(going)
- {
- struct IntuiMessage* intuimsg;
- /* Wait for messages to arrive */
- WaitPort(win->UserPort);
- /* Messages have arrived: loop through all of them */
- while(intuimsg = GT_GetIMsg(win->UserPort))
- {
- /* Act on this message... */
- switch(intuimsg->Class)
- {
- case IDCMP_MOUSEBUTTONS:
- switch(intuimsg->Code)
- {
- case SELECTDOWN:
- drawing = TRUE;
- break;
- case SELECTUP:
- drawing = FALSE;
- break;
- }
- /* break; omitted so we draw on click, too */
- case IDCMP_MOUSEMOVE:
- /* Don't draw on top gap which holds gadgets */
- if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
- {
- Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
- Text(win->RPort, text, strlen(text));
- }
- break;
- case IDCMP_CLOSEWINDOW:
- going = FALSE;
- break;
- case IDCMP_REFRESHWINDOW:
- /* You *MUST* remember to ask for and handle these refresh messages */
- GT_BeginRefresh(win);
- GT_EndRefresh(win, TRUE);
- break;
- case IDCMP_GADGETUP:
- /* Trick: introduce new "{..}" scope so we can declare gad locally */
- {
- struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
- switch(gad->GadgetID)
- {
- case MYBUT_ID:
- /* Our button was clicked! Set foreground to next pen colour */
- setFgPen(win, pen+1);
- break;
- case MYPAL_ID:
- /* Our palette gadget was clicked! Set foreground to gadget colour */
- setFgPen(win, intuimsg->Code);
- break;
- }
- break;
- }
- case IDCMP_MENUPICK:
- /* Again, use trick to introduce new "{..}" scope */
- {
- UWORD menuCode, menuNumber, itemNumber;
- /* Loop over all the menu selections in the menu code */
- for(menuCode = intuimsg->Code;
- going && menuCode != MENUNULL;
- menuCode = ItemAddress(win->MenuStrip, menuCode)->NextSelect)
- {
- /* Extract the menu number and menu item number from the menu code */
- menuNumber = MENUNUM(menuCode);
- itemNumber = ITEMNUM(menuCode);
- /* Now decide what to do based on what menu item was selected */
- switch(menuNumber)
- {
- case 0: /* Project menu */
- /* Only one item: Quit */
- if(itemNumber == 0)
- going = FALSE;
- break;
- case 1: /* Pen menu */
- switch(itemNumber)
- {
- case 0: /* Next */
- setFgPen(win, pen+1);
- break;
- case 1: /* Prev */
- setFgPen(win, pen-1);
- break;
- case 3: /* Reset (item 2 is the bar!)*/
- setFgPen(win, MYINITPEN);
- break;
- }
- break;
- }
- }
- break;
- }
- }
- /* Reply when finished with message */
- GT_ReplyIMsg(intuimsg);
- }
- }
- }
-
- void setFgPen(struct Window* win, int value)
- {
- /* Wrap when reached the end of the palette gadget's colours */
- pen = value % (1<<MYPAL_DEPTH);
- SetAPen(win->RPort, pen);
- if(palgad)
- {
- /* Update palette gadget with new pen value */
- GT_SetGadgetAttrs(palgad, win, NULL, GTPA_Color, pen, TAG_DONE);
- }
- }
-